#!/usr/bin/python
import ConfigParser
import hashlib
import tarfile
import os
import tempfile
import time


class Enumerate(object):
    def __init__(self, names):
        for number, name in enumerate(names.split()):
            setattr(self, name, number)

class deploy:
    def __init__(self):
        self.install = {};
        self.getConfig();
        self.backup = 0;

    def getConfig(self):
        config=ConfigParser.ConfigParser()
        config.read("deploy.conf")

        for service in config.sections():
            if service == "info":
                continue
            objs =  config.options(service)
            pairs = []
            for obj in objs:
                pairs.append([os.path.normpath(obj), os.path.normpath(config.get(service,obj))]);
            self.install[service] = pairs
        if config.has_option("info","backup"):
            self.backup = 1; ##need modify such code

    def saveBackup(self,serviceName):
       os.system("cp "+serviceName+".tar "+serviceName+time.strftime( '%Y-%m-%d-%X', time.localtime() )+".tar")

    def MD5File(self, fileName):
        try:
            f = file(fileName,'rb')
        except:
            print 'Failed to open file '+f;
            exit;
        m = hashlib.md5();
        while True:
            d = f.read(8096)
            if not d:
                break;
            m.update(d)
        return m.hexdigest()

    def unpackage(self, ins):
        tempf = tempfile.mkdtemp();
        tar = tarfile.open(ins+".tar", "r")
        names = tar.getnames()
        for name in names:
            tar.extract(name,path=tempf)
        tar.close()
        self.source = tempf
        

    def installService(self, service):
        for pair in self.install[service]:
            if os.path.isfile(os.path.join( self.source, pair[0])):
                os.system("cp -rf "+os.path.join( self.source, pair[0] )+" "+pair[1])
            elif  os.path.isdir( os.path.join( self.source, pair[0] ) ):
                if os.path.exists( pair[1] ):
                    os.system("cp -rf "+os.path.join( self.source, pair[0] )+"/* "+pair[1])
                else:
                    os.system("cp -rf "+os.path.join( self.source, pair[0] )+" "+pair[1])
                     
 
    def getDestination(self, service, sourcePath):
        normSourcePath = os.path.normpath(sourcePath)
        if self.install.has_key(service) :
            for pair in self.install[service]:
                if not os.path.exists(pair[0]):
                    print "there are no such file:",pair[0]
                    exit(1)
                common = os.path.commonprefix([pair[0], normSourcePath])
                if os.path.samefile(os.path.join(self.source,common),os.path.join(self.source, pair[0])):
                     return normSourcePath.replace(pair[0], pair[1])
        return NULL 

    def verifyInstall(self, service):
        md5File = file(os.path.join(self.source, "MD5SUM"), "rb")
        while True:
            d = md5File.readline()
            if not d:
                break
            md5 = d.split()
            des = self.getDestination( service, md5[0])
            print "START MD5 CHECK ",des
            value  = self.MD5File(des)
            if value != md5[1]:
                return False;
        print "DEPLOY SUCCESSFUL!"
        return True;

    def verifySrc(self,serviceName):
        if not os.path.isfile(serviceName+".tar"):
            print "NO INSTALL FILE ",serviceName,".tar"
        self.unpackage(serviceName)
        files = []
        md5File = file(os.path.join(self.source, "MD5SUM"), "rb")
        while True:
            d = md5File.readline()
            if not d:
                break
            md5 = d.split()
            sourceFile = os.path.join(self.source,md5[0])
            if not os.path.isfile(sourceFile):
                print "SOURCE FILE(TAR) IS BROKEN, ERROR"
                exit(1)
            value = self.MD5File(sourceFile)
            if value != md5[1]:
                print "SOURCE FILE(TAR) IS BROKEN, ERROR"
                exit(1)
            files.append(sourceFile)
        for parent, dirnames, filenames in os.walk(self.source):
            if len(filenames):
                for filename in filenames:
                    if filename == "MD5SUM":
                        continue
                    checkFlag = False
                    rePath = os.path.join( parent, filename );
                    for testFile in files:
                        if os.path.samefile(testFile, rePath):
                            checkFlag = True;
                            break;
                        else:
                            continue;
                    if not checkFlag:
                        print "SOURCE FILE(TAR) IS BROKEN, ERROR ",rePath
                        exit(1)

        print "TAR CHECK OK"
        return True;


de =deploy()
de.verifySrc("online")
de.saveBackup("online")
de.installService("online")
de.verifyInstall("online")
